/*
 * Copyright (C) 2008 Universidade Federal de Campina Grande
 *  
 * This file is part of OurGrid. 
 *
 * OurGrid is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free 
 * Software Foundation, either version 3 of the License, or (at your option) 
 * any later version. 
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public License 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package org.ourgrid.broker.business.scheduler.workqueue.statemachine;

import org.ourgrid.broker.business.messages.WorkerClientMessages;
import org.ourgrid.broker.business.scheduler.extensions.GenericTransferProgress;
import org.ourgrid.broker.business.scheduler.workqueue.WorkQueueExecutionController;
import org.ourgrid.broker.business.scheduler.workqueue.xmlcreator.LoggerXMLCreator;
import org.ourgrid.broker.business.schedulerdata.SchedulerData;
import org.ourgrid.broker.communication.operations.GridProcessOperations;
import org.ourgrid.common.executor.ExecutorResult;
import org.ourgrid.common.filemanager.FileInfo;
import org.ourgrid.common.interfaces.to.IncomingHandle;
import org.ourgrid.common.interfaces.to.OutgoingHandle;
import org.ourgrid.common.job.GridProcess;
import org.ourgrid.worker.business.controller.GridProcessError;

/**
 *
 */
public class ScheduledState extends AbstractRunningState {
	
	private final String STATE_NAME = "Scheduled";

	public ScheduledState(WorkQueueExecutionController heuristic) {
		super(heuristic);
	}

	/* (non-Javadoc)
	 * @see org.ourgrid.broker.controller.states.RunningState#errorOcurred(org.ourgrid.worker.controller.ExecutionError)
	 */
	public void errorOcurred(GridProcessError error, GridProcess execution) {
		fail(error, execution);
	}

	public void fileRejected(OutgoingHandle handle, GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("fileRejected", STATE_NAME), 
						LoggerXMLCreator.WARN)));
	}

	public void fileTransferRequestReceived(IncomingHandle handle, GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("fileTransferRequestReceived", STATE_NAME), 
						LoggerXMLCreator.WARN)));
	}

	/* (non-Javadoc)
	 * @see org.ourgrid.broker.controller.states.RunningState#hereIsExecutionResult(org.ourgrid.common.executor.ExecutorResult)
	 */
	public void hereIsExecutionResult(ExecutorResult result, GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("hereIsExecutionResult", STATE_NAME), 
						LoggerXMLCreator.WARN)));
	}

	public void hereIsFileInfo(long operationHandle, FileInfo fileInfo, GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("hereIsFileInfo", STATE_NAME), 
						LoggerXMLCreator.WARN)));

	}

	public void incomingTransferCompleted(IncomingHandle handle, long amountWritten, GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("incomingTransferCompleted", 
						STATE_NAME), 
						LoggerXMLCreator.WARN)));
	}

	public void incomingTransferFailed(IncomingHandle handle, Exception failCause, long amountWritten, 
			GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("incomingTransferFailed", STATE_NAME), 
						LoggerXMLCreator.WARN)));
	}

	public void outgoingTransferCancelled(OutgoingHandle handle, long amountWritten, GridProcess gridProcess) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("outgoingTransferCancelled", 
						STATE_NAME), 
						LoggerXMLCreator.ERROR)));
	}

	public void outgoingTransferCompleted(OutgoingHandle handle, long amountWritten, GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("outgoingTransferCompleted",
						STATE_NAME), 
						LoggerXMLCreator.ERROR)));
	}

	public void outgoingTransferFailed(OutgoingHandle handle, String failCause, long amountWritten, 
			GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("outgoingTransferFailed", STATE_NAME), 
						LoggerXMLCreator.ERROR)));
	}

	public void updateTransferProgress(GenericTransferProgress fileTransferProgress, GridProcess execution) {
		
		getCollector().addData(new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getRunningStateInvalidOperation("updateTransferProgress", STATE_NAME), 
						LoggerXMLCreator.ERROR)));
	}

	/* (non-Javadoc)
	 * @see org.ourgrid.broker.controller.states.RunningState#workerIsReady()
	 */
	public void workerIsReady(GridProcess execution) {
		GridProcessOperations operations = execution.getOperations();
		
		SchedulerData loggerData = new SchedulerData(getXmlCreator(LoggerXMLCreator.class).
				getXML(WorkerClientMessages.getWorkerIsReadyMessage(execution.getHandle(), execution.getState()), 
						LoggerXMLCreator.DEBUG));
		
		getCollector().addData(loggerData);
		
		if (!operations.areAllInitPhaseOperationsFinished()) {
			execution.setRunningState(new InitState(getHeuristic()));
			execution.getResult().setInitPhaseStartTime();
			runOperations(operations.getInitPhaseOperationsList(), execution);
			
		} else if (!operations.isRemotePhaseOperationFinished()) {
			execution.setRunningState(new RemoteState(getHeuristic()));
			execution.getResult().setRemotePhaseStartTime();
			execution.startCPUTiming();
			runOperation(operations.getRemotePhaseOperation(), execution);
		}
	}
	
}
